<!DOCTYPE html>

<html>
<head>
  <title>layer.coffee</title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  <link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
  <div id="container">
    <div id="background"></div>
    
      <ul id="jump_to">
        <li>
          <a class="large" href="javascript:void(0);">Jump To &hellip;</a>
          <a class="small" href="javascript:void(0);">+</a>
          <div id="jump_wrapper">
          <div id="jump_page">
            
              
              <a class="source" href="analyze.html">
                analyze.coffee
              </a>
            
              
              <a class="source" href="autoload.html">
                autoload.coffee
              </a>
            
              
              <a class="source" href="blender.html">
                blender.coffee
              </a>
            
              
              <a class="source" href="calculate.html">
                calculate.coffee
              </a>
            
              
              <a class="source" href="caman.html">
                caman.coffee
              </a>
            
              
              <a class="source" href="convert.html">
                convert.coffee
              </a>
            
              
              <a class="source" href="event.html">
                event.coffee
              </a>
            
              
              <a class="source" href="filter.html">
                filter.coffee
              </a>
            
              
              <a class="source" href="io.html">
                io.coffee
              </a>
            
              
              <a class="source" href="layer.html">
                layer.coffee
              </a>
            
              
              <a class="source" href="logger.html">
                logger.coffee
              </a>
            
              
              <a class="source" href="module.html">
                module.coffee
              </a>
            
              
              <a class="source" href="pixel.html">
                pixel.coffee
              </a>
            
              
              <a class="source" href="plugin.html">
                plugin.coffee
              </a>
            
              
              <a class="source" href="renderer.html">
                renderer.coffee
              </a>
            
              
              <a class="source" href="store.html">
                store.coffee
              </a>
            
              
              <a class="source" href="util.html">
                util.coffee
              </a>
            
              
              <a class="source" href="blenders.html">
                blenders.coffee
              </a>
            
              
              <a class="source" href="filters.html">
                filters.coffee
              </a>
            
              
              <a class="source" href="size.html">
                size.coffee
              </a>
            
              
              <a class="source" href="blur.html">
                blur.coffee
              </a>
            
              
              <a class="source" href="camera.html">
                camera.coffee
              </a>
            
              
              <a class="source" href="compoundBlur.html">
                compoundBlur.coffee
              </a>
            
              
              <a class="source" href="edges.html">
                edges.coffee
              </a>
            
              
              <a class="source" href="posterize.html">
                posterize.coffee
              </a>
            
              
              <a class="source" href="presets.html">
                presets.coffee
              </a>
            
              
              <a class="source" href="rotate.html">
                rotate.coffee
              </a>
            
              
              <a class="source" href="stackBlur.html">
                stackBlur.coffee
              </a>
            
              
              <a class="source" href="threshold.html">
                threshold.coffee
              </a>
            
          </div>
        </li>
      </ul>
    
    <ul class="sections">
        
          <li id="title">
              <div class="annotation">
                  <h1>layer.coffee</h1>
              </div>
          </li>
        
        
        
        <li id="section-1">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-1">&#182;</a>
              </div>
              <p>The entire layering system for Caman resides in this file. Layers get their own canvasLayer 
objectwhich is created when newLayer() is called. For extensive information regarding the 
specifics of howthe layering system works, there is an in-depth blog post on this very topic. 
Instead of copying the entirety of that post, I&#39;ll simply point you towards the 
<a href="http://blog.meltingice.net/programming/implementing-layers-camanjs">blog link</a>.</p>
<p>However, the gist of the layering system is that, for each layer, it creates a new canvas 
element and then either copies the parent layer&#39;s data or applies a solid color to the new 
layer. After some (optional) effects are applied, the layer is blended back into the parent 
canvas layer using one of many different blending algorithms.</p>
<p>You can also load an image (local or remote, with a proxy) into a canvas layer, which is useful 
if you want to add textures to an image.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="class"><span class="keyword">class</span> <span class="title">Caman</span>.<span class="title">Layer</span></span>
  constructor: (<span class="property">@c</span>) -&gt;</pre></div></div>
            
        </li>
        
        
        <li id="section-2">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-2">&#182;</a>
              </div>
              <p>Compatibility</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="property">@filter</span> = <span class="property">@c</span>
    
    <span class="property">@options</span> =
      blendingMode: <span class="string">'normal'</span>
      opacity: <span class="number">1.0</span></pre></div></div>
            
        </li>
        
        
        <li id="section-3">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-3">&#182;</a>
              </div>
              <p>Each layer gets its own unique ID</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="property">@layerID</span> = Util.uniqid.get()</pre></div></div>
            
        </li>
        
        
        <li id="section-4">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-4">&#182;</a>
              </div>
              <p>Create the canvas for this layer</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="property">@canvas</span> = <span class="keyword">if</span> exports? <span class="keyword">then</span> <span class="keyword">new</span> Canvas() <span class="keyword">else</span> document.createElement(<span class="string">'canvas'</span>)
    
    <span class="property">@canvas</span>.width = <span class="property">@c</span>.dimensions.width
    <span class="property">@canvas</span>.height = <span class="property">@c</span>.dimensions.height

    <span class="property">@context</span> = <span class="property">@canvas</span>.getContext(<span class="string">'2d'</span>)
    <span class="property">@context</span>.createImageData <span class="property">@canvas</span>.width, <span class="property">@canvas</span>.height
    <span class="property">@imageData</span> = <span class="property">@context</span>.getImageData <span class="number">0</span>, <span class="number">0</span>, <span class="property">@canvas</span>.width, <span class="property">@canvas</span>.height
    <span class="property">@pixelData</span> = <span class="property">@imageData</span>.data</pre></div></div>
            
        </li>
        
        
        <li id="section-5">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-5">&#182;</a>
              </div>
              <p>If you want to create nested layers</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  newLayer: (cb) -&gt; <span class="property">@c</span>.newLayer.call <span class="property">@c</span>, cb</pre></div></div>
            
        </li>
        
        
        <li id="section-6">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-6">&#182;</a>
              </div>
              <p>Sets the blending mode of this layer. The mode is the name of a blender function.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  setBlendingMode: (mode) -&gt;
    <span class="property">@options</span>.blendingMode = mode
    <span class="keyword">return</span> @</pre></div></div>
            
        </li>
        
        
        <li id="section-7">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-7">&#182;</a>
              </div>
              <p>Sets the opacity of this layer. This affects how much of this layer is applied to the parent
layer at render time.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  opacity: (opacity) -&gt;
    <span class="property">@options</span>.opacity = opacity / <span class="number">100</span>
    <span class="keyword">return</span> @</pre></div></div>
            
        </li>
        
        
        <li id="section-8">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-8">&#182;</a>
              </div>
              <p>Copies the contents of the parent layer to this layer</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  copyParent: -&gt;
    parentData = <span class="property">@c</span>.pixelData

    <span class="keyword">for</span> i <span class="keyword">in</span> [<span class="number">0.</span>..<span class="property">@c</span>.pixelData.length] <span class="keyword">by</span> <span class="number">4</span>
      <span class="property">@pixelData</span>[i]   = parentData[i]
      <span class="property">@pixelData</span>[i+<span class="number">1</span>] = parentData[i+<span class="number">1</span>]
      <span class="property">@pixelData</span>[i+<span class="number">2</span>] = parentData[i+<span class="number">2</span>]
      <span class="property">@pixelData</span>[i+<span class="number">3</span>] = parentData[i+<span class="number">3</span>]

    <span class="keyword">return</span> @</pre></div></div>
            
        </li>
        
        
        <li id="section-9">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-9">&#182;</a>
              </div>
              <p>Fills this layer with a single color</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  fillColor: -&gt; <span class="property">@c</span>.fillColor.apply <span class="property">@c</span>, arguments</pre></div></div>
            
        </li>
        
        
        <li id="section-10">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-10">&#182;</a>
              </div>
              <p>Loads and overlays an image onto this layer</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  overlayImage: (image) -&gt;
    <span class="keyword">if</span> <span class="keyword">typeof</span> image <span class="keyword">is</span> <span class="string">"object"</span>
      image = image.src
    <span class="keyword">else</span> <span class="keyword">if</span> <span class="keyword">typeof</span> image <span class="keyword">is</span> <span class="string">"string"</span> <span class="keyword">and</span> image[<span class="number">0</span>] <span class="keyword">is</span> <span class="string">"#"</span>
      image = $(image).src

    <span class="keyword">return</span> @ <span class="keyword">if</span> <span class="keyword">not</span> image

    <span class="property">@c</span>.renderer.renderQueue.push
      type: Filter.Type.LoadOverlay
      src: image
      layer: @

    <span class="keyword">return</span> @</pre></div></div>
            
        </li>
        
        
        <li id="section-11">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-11">&#182;</a>
              </div>
              <p>Takes the contents of this layer and applies them to the parent layer at render time. This
should never be called explicitly by the user.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  applyToParent: -&gt;
    parentData = <span class="property">@c</span>.pixelStack[<span class="property">@c</span>.pixelStack.length - <span class="number">1</span>]
    layerData = <span class="property">@c</span>.pixelData
    
    <span class="keyword">for</span> i <span class="keyword">in</span> [<span class="number">0.</span>..layerData.length] <span class="keyword">by</span> <span class="number">4</span>
      rgbaParent =
        r: parentData[i]
        g: parentData[i+<span class="number">1</span>]
        b: parentData[i+<span class="number">2</span>]
        a: parentData[i+<span class="number">3</span>]

      rgbaLayer =
        r: layerData[i]
        g: layerData[i+<span class="number">1</span>]
        b: layerData[i+<span class="number">2</span>]
        a: layerData[i+<span class="number">3</span>]

      result = Blender.execute <span class="property">@options</span>.blendingMode, rgbaLayer, rgbaParent

      result.r = Util.clampRGB result.r
      result.g = Util.clampRGB result.g
      result.b = Util.clampRGB result.b
      result.a = rgbaLayer.a <span class="keyword">if</span> <span class="keyword">not</span> result.a?

      parentData[i]   = rgbaParent.r - (
        (rgbaParent.r - result.r) * (<span class="property">@options</span>.opacity * (result.a / <span class="number">255</span>))
      )
      parentData[i+<span class="number">1</span>] = rgbaParent.g - (
        (rgbaParent.g - result.g) * (<span class="property">@options</span>.opacity * (result.a / <span class="number">255</span>))
      )
      parentData[i+<span class="number">2</span>] = rgbaParent.b - (
        (rgbaParent.b - result.b) * (<span class="property">@options</span>.opacity * (result.a / <span class="number">255</span>))
      )

Layer = Caman.Layer</pre></div></div>
            
        </li>
        
    </ul>
  </div>
</body>
</html>
